package com.gjy.redis.controller;

import com.gjy.redis.domain.AjaxResult;
import com.gjy.redis.domain.vo.SetAddRequest;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RScript;
import org.redisson.api.RSet;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-07-17 11:00:16
 */
@RestController
@Slf4j
@RequestMapping("/set")
public class SetController {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private Redisson redisson1;
    @Resource
    private Jedis jedis;

    @PostMapping("/raffle2")
    public AjaxResult raffle2() {
        /*jedis.scan("", new ScanParams());*/

        /*Pipeline pipelined = jedis.pipelined();
        List<Object> objects = pipelined.syncAndReturnAll();*/


        // 初始化阶段
        if (!jedis.exists("S1")) {
            jedis.sadd("S1", "1", "2", "3", "4", "5");
        }
        log.info("s1: {}", jedis.smembers("S1"));

        String s = "if redis.call(\"get\", \"counter\") then\n" +
                "    redis.call(\"incr\", \"counter\")\n" +
                "else\n" +
                "    redis.call(\"set\", \"counter\", \"1\")\n" +
                "end\n" +
                "\n" +
                "if tonumber(redis.call(\"get\", \"counter\")) > 3 then\n" +
                "    return \"抽奖已结束\"\n" +
                "end\n" +
                "return redis.call(\"spop\", KEYS[1])";
        String load = jedis.scriptLoad(s);
        log.info("load: {}", load);
        Object execute = jedis.evalsha(load, 1, "S1");

        log.info("execute:{}", execute);
        return AjaxResult.builder().data(execute).build();
    }

    @PostMapping("/raffle")
    public AjaxResult raffle() {
        // 初始化阶段
        RSet<Object> s1 = redisson1.getSet("S1");
        if (s1.size() == 0) {
            s1.addAll(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
        }
        log.info("s1: {}", s1);

        String s = "if redis.call(\"get\", \"counter\") then\n" +
                "    redis.call(\"incr\", \"counter\")\n" +
                "else\n" +
                "    redis.call(\"set\", \"counter\", \"1\")\n" +
                "end\n" +
                "\n" +
                "if tonumber(redis.call(\"get\", \"counter\")) > 3 then\n" +
                "    return \"抽奖已结束\"\n" +
                "end\n" +
                "return redis.call(\"spop\", KEYS[1])";
        RScript script = redisson1.getScript();
        String load = script.scriptLoad(s);
        log.info("load: {}", load);
        Object execute = script.evalSha(RScript.Mode.READ_WRITE, load,
                RScript.ReturnType.VALUE, Lists.newArrayList("S1"));
        log.info("execute:{}", execute);
        return AjaxResult.builder().data(execute).build();
    }

    @PostMapping("/readFile")
    public AjaxResult readFile(@RequestParam MultipartFile file) throws IOException {
        String name = file.getName();
        String originalFilename = file.getOriginalFilename();
        String contentType = file.getContentType();
        long size = file.getSize();
        InputStream inputStream = file.getInputStream();
        byte[] b = new byte[Math.toIntExact(size)];
        inputStream.read(b, 0, (int) size);
        log.info("name:{}, oname:{}, content:{}, size:{}", name, originalFilename, contentType, size);
        return AjaxResult.builder().data(new String(b)).build();
    }

    @PostMapping("/add")
    public AjaxResult add(@RequestBody SetAddRequest request) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        Long s1 = set.add("S1", request.getValues().toArray());
        return AjaxResult.builder().data(s1).build();
    }

    @PostMapping("/spop")
    public AjaxResult spop() {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        Object s1 = set.pop("S1");
        return AjaxResult.builder().data(s1).build();
    }

}
